iT邦幫忙

0

Laravel 技術筆記 (四)【Query Builder 查詢建構器】

  • 分享至 

  • xImage
  •  

介紹

在上一篇使用遷移定義好資料庫的架構後,我們還需要學習如何與資料庫互動,在 Laravel 中我們可以不必使用原生的 SQL 語法來操作資料庫,Laravel 提供一種流暢的語法來取代這些操作,比起原生語法更直覺方便和安全。


靜態呼叫

https://ithelp.ithome.com.tw/upload/images/20220312/20135794A0Rsk58SAV.jpg
今天假設我有一資料表 users 存放使用者的資料,在使用原生 SQL 要取得所有資料時,會使用這樣的語句:

select * from `users`

而若要改使用查詢建構器取得所有資料時,Laravel 支援 DB 靜態呼叫的方法:

/* 使用查詢建構器時,需使用 DB 的名稱空間 */
use Illuminate\Support\Facades\DB;

DB::table('users')->get();

上面使用 SQL 和查詢建構器的兩種語法結果是相同的,下面會介紹許多常用的查詢建構器。


  • select():回傳較小的資料集合,可指定回傳特定欄位。
/* 只會回傳 name 和 password 兩個欄位的資料 */
DB::table('users')->select('name', 'password')->get();
  • where():限制回傳資料的範圍,和原生 SQL 的 where 用途相同。
/* 取得 id = 1 的資料 */
DB::table('users')->where('id', '1')->get();
/* 取得 id > 1 的資料 */
DB::table('users')->where('id', '>', '1')->get();
  • orWhere():
/* 取得 id = 1 或 name = Tom 的資料 */
DB::table('users')->where('id', '1')->orWhere('name', 'Tom')->get();

這邊要注意到如果使用多個 where() 與 orWhere() 可能會造成查詢語句上的混淆,各位可以思考看看下面這樣的查詢建構器實際上會取的怎樣的資料:

DB::table('users')->where('id', '>', '1')->orWhere('name', 'Tom')->where('password', '3456')->get();

上面的查詢建構器實際上會符合這樣的 SQL 語句:

select * from `users` where `id` > 1 or `name` = 'Tom' and `password` = '3456'

這邊會發現 where() 是使用 and 去銜接,而 orWhere() 則是使用 or,由於 and 的優先度會高於 or,在使用上務必注意此點。

  • whereBetween():限制查詢的範圍。
/* 取得 id 2 ~ 5 的資料 */
DB::table('users')->whereBetween('id', [2, 5])->get();
  • whereNotBetween():與 whereBetween() 相反的查詢。
/* 取得 id 不在 2 ~ 5 的資料 */
DB::table('users')->whereNotBetween('id', [2, 5])->get();
  • whereIn():可將查詢的限制範圍以陣列回傳。
/* 取得 id = 2 和 5 的資料 */
DB::table('users')->whereIn('id', [2, 5])->get();
  • whereNull():取得特定欄位為 Null 或 Not Null 的資料。
  • whereNotNull():取得特定欄位為 Not Null 的資料。
  • distinct():通常搭配 select() 一起使用,只會顯示不重覆值的資料。
/* 此範例為一錯誤示範,id 為資料表的主鍵欄位,代表 id 不會有重覆值,使用 distinct() 做查詢的話會沒有結果 */
DB::table('users')->select('id')->distinct()->get();
  • orderBy():將查詢結果做排序。
/* 第二個參數支援 asc(升序,預設) 與 desc(降序) */
DB::table('users')->orderBy('id', 'desc')->get();
  • groupBy():將查詢結果中指定欄位值相同的資料分為若干個群組,每一組只會回傳一組資料,常常搭配 count()、sum()、max()、min()、avg() 使用。
/* 由於 city 欄位中有兩組 Tatpei 資料,所以只會得到四筆資料(Jhon 和 Zorn 分為一組,所以只取得 John 的資料,再加上 James、Tom、Jack 三筆總共四筆) */
DB::table('users')->groupBy('city')->get();
  • skip():跳過指定數目的資料筆數。
  • take():取得指定數目的資料筆數。
/* 跳過第 1 筆取得後面頭 2 筆的資料,最常用來製作分頁 */
DB::table('users')->skip(1)->take(2)->get();
  • latest():以傳入的欄位來升序,若沒傳入參數,以 created_at 為準。
  • oldest():以傳入的欄位來降序,若沒傳入參數,以 created_at 為準。
  • inRandomOrder():亂數排序結果。
  • get():取得已建立的查詢結果,通常放在最後一個。
  • first():類似 get(),但只取得第一筆資料。
  • find():可傳入主鍵 id 值。
  • value():類似 first(),可指定某一特定欄位。
/* 回傳 John */
DB::table('users')->value('name');
  • count():回傳查詢結果資料的總筆數。
/* 回傳 6 */
DB::table('users')->count();
  • max():回傳欄位的最大值。
  • min():回傳欄位的最小值。
  • sum():回傳特定欄位的總和。
/* 回傳 195 */
DB::table('users')->sum('age');
  • avg():回傳特定欄位的平均值。
/* 回傳 32.5 */
DB::table('users')->avg('age');

連結

  • join():內部連結。
/* 符合連結條件的資料才會顯示 */
DB::table('users')->join('contacts', 'users.id', '=', 'contacts.user_id')->get();
  • leftJoin():左外部連結。
/* 左側資料表的所有資料會加入查詢結果,即使沒有符合連結條件的資料也會顯示 */
DB::table('users')->leftJoin('contacts', 'users.id', '=', 'contacts.user_id')->get();
  • rightJoin():右外部連結,與 leftJoin() 一樣,只差在是以右側資料表為主。

插入

  • insert():插入語句。
DB::table('users')->insert([
    ['email' => 'picard@gmail.com', 'age' => 36],
    ['email' => 'janeway@gmail.com', 'age' => 48],
]);

更新

  • update():更新語句。
DB::table('users')
    ->where('id', 1)
    ->update(['age' => 16]);

刪除

  • delete():刪除語句。
DB::table('users')->where('id', 2)->delete();

原生查詢

  • DB::raw():可放在查詢建構器中使用原生 SQL 語法。
/* 取得所有用戶居住城市的分組資料 */
DB::table('users')->select(DB::raw('city, count(city) as count'))->groupBy('city')->get();

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言